﻿using System;
using System.Web;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Linq;
using NENAData.Errors;
using NENAData.Factory;
using NENAData.LINQ;
using NENAData.EF;

namespace NENAData.Transactions.Payments.PayPal
{
    public class PayPalTransactions
    {
        public enum TransactionTypes
        {
            express_checkout
        }
         

        private static MembershipDataContext GetMembershipDB()
        {
            var x = new SQLMembership();
            return x.GetMembershipDB();
        }

        private static NENA_MembershipEntities GetConnection()
        {
            var x = new SQLMembership();
            return x.DBConnection();
        }

        public void SaveIPN(string strMessage)
        {
            MembershipDataContext db = GetMembershipDB();

            LINQ.PayPal_IPN oIPN = new LINQ.PayPal_IPN
                {
                    Message = strMessage
                };

            db.PayPal_IPNs.InsertOnSubmit(oIPN);
            db.SubmitChanges();
        }

        public PayPal_IPN_Full ParseAndSaveIPN(string strMessage)
        {
            NENA_MembershipEntities db = GetConnection();

            decimal mcFee = 0;
            decimal mcGross = 0;
            string sContactPhone = string.Empty;
            //depending the type; these values may not exist
            try
            {
                mcFee = Convert.ToDecimal(FindInString(strMessage, "mc_fee="));
                mcGross = Convert.ToDecimal(FindInString(strMessage, "mc_gross="));
                sContactPhone = FindInString(strMessage, "contact_phone=");
            }
            catch
            {
            }

            PayPal_IPN_Full oIPN = new PayPal_IPN_Full
            {
                //payerId = Request.QueryString["PayerId"] == "" ? Session["PayerId"].ToString() : Request.QueryString["PayerId"];
                Payment_Mc_Fee = mcFee,
                Payment_Mc_Gross = mcGross,
                Paypal_Payer_Id = FindInString(strMessage, "payer_id="),
                Paypal_Transaction_Id = FindInString(strMessage, "txn_id="),
                Transaction_Type = FindInString(strMessage, "txn_type="),
                //Payment_Date = Convert.ToDateTime(FindInString(strMessage, "payment_date=")), cannot convert format
                Payer_Full_Name = FindInString(strMessage, "address_name="),
                Payment_Status = FindInString(strMessage, "payment_status="),
                Payer_Email = FindInString(strMessage, "payer_email=", true),
                Payment_To = FindInString(strMessage, "receiver_email=", true),
                Payer_Phone_Number = sContactPhone,
                Payment_Type = FindInString(strMessage, "payment_type="),
                IPN_Date = DateTime.Now,
                IPN_Message = strMessage                                
            };
            db.AddToPayPal_IPN_Full(oIPN);
            db.SaveChanges();

            return oIPN;
        }

        private string FindInString(string strMessage, string strvalue, bool boolEscape = false)
        {
            int intStart = strMessage.IndexOf(strvalue);
            int intStartValue = intStart + strvalue.Length;
            int intEndLocation = strMessage.IndexOf("&", intStartValue);

            string strReturn = strMessage.Substring(intStartValue, intEndLocation - intStartValue);

            if (boolEscape)
            {
                //doesn't work
                //http://stackoverflow.com/questions/183907/how-do-convert-unicode-escape-sequences-to-unicode-characters-in-a-net-string
                //Regex regex = new Regex(@"\\[uU]([0-9A-F]{4})", RegexOptions.IgnoreCase);
                Regex regex = new Regex(@"(%40)", RegexOptions.IgnoreCase);                
                //var al = regex.Replace(strReturn, match => ((char)int.Parse(match.Groups[1].Value, NumberStyles.HexNumber)).ToString());
                strReturn = regex.Replace(strReturn, "@");
            }

            return strReturn ?? string.Empty;
        }


        public LINQ.TransactionPayment GetPayPalTransaction(string strTransactionID_PayPal)
        {
            MembershipDataContext db = GetMembershipDB();
            LINQ.TransactionPayment MemberTransaction = (from t1 in db.TransactionPayments
                                        where t1.TransactionID_PayPal == strTransactionID_PayPal
                                        select t1).Single();

            return MemberTransaction;
        }

        public void NewTemplatePayPal(string strToken, string strAmount, int intMemberID, int intPaymentTo, int intTransactionID_NENA)
        {
            MembershipDataContext db = GetMembershipDB();

            LINQ.TransactionPayment NENAtransaction = new LINQ.TransactionPayment
                                                     {
                                                         TokenID = strToken,
                                                         Member_ID = intMemberID,
                                                         PaymentTo = intPaymentTo,
                                                         PaymentAmount = Convert.ToDouble(strAmount),
                                                         TransactionCompleted = false,
                                                         PaymentType = "PayPal",
                                                         PaymentStatus = "Transferred To PayPal",
                                                         TransactionStartedDate = DateTime.Now,
                                                         TransactionID_NENA = intTransactionID_NENA,
                                                         PaymentDate = null
                                                     };

            db.TransactionPayments.InsertOnSubmit(NENAtransaction);
            db.SubmitChanges();
        }

        public int NewTemplatePayPal(string strAmount, int intMemberID, int intPaymentTo, int intTransactionID_NENA)
        {
            MembershipDataContext db = GetMembershipDB();

            LINQ.TransactionPayment NENAtransaction = new LINQ.TransactionPayment
            {
                TokenID = "",
                Member_ID = intMemberID,
                PaymentTo = intPaymentTo,
                PaymentAmount = Convert.ToDouble(strAmount),
                TransactionCompleted = false,
                PaymentType = "PayPal",
                PaymentStatus = "Transferred To PayPal",
                TransactionStartedDate = DateTime.Now,
                TransactionID_NENA = intTransactionID_NENA,
                PaymentDate = null
            };

            db.TransactionPayments.InsertOnSubmit(NENAtransaction);
            db.SubmitChanges();

            return NENAtransaction.TransactionPaymentID;
        }

        public void UpdateFullPayPal_byToken(string strToken, string strPayerID, NVPCodec NVPtransaction, ref int intMemberID, ref int intTransactionPaymentID)
        {

            try
            {

                MembershipDataContext db = GetMembershipDB();
                var MemberTransaction = (from t1 in db.TransactionPayments
                                         where t1.TokenID == strToken
                                         select t1).Single();

                MemberTransaction.PayerID = strPayerID;
                MemberTransaction.TokenID = strToken;
                MemberTransaction.PaymentAmount = Convert.ToDouble(NVPtransaction["PAYMENTINFO_0_AMT"]);
                MemberTransaction.TransactionID_PayPal = NVPtransaction["PAYMENTINFO_0_TRANSACTIONID"];
                //todo: add nenatransactionID
                //MemberTransaction.TransactionType = NVPtransaction["TRANSACTIONTYPE"];
                //MemberTransaction.PaymentMethod = "PayPal";
                MemberTransaction.PaymentMethod = NVPtransaction["PAYMENTINFO_0_PAYMENTTYPE"];
                MemberTransaction.PaymentStatus = NVPtransaction["PAYMENTINFO_0_PAYMENTSTATUS"];
                MemberTransaction.PayPalFee = Convert.ToDouble(NVPtransaction["PAYMENTINFO_0_FEEAMT"]);
                MemberTransaction.PaymentDate = DateTime.Now;
                MemberTransaction.PaymentReason = "MembershipFees";
                if (MemberTransaction.PaymentStatus == "Completed")
                {
                    MemberTransaction.TransactionCompleted = true;
                    intMemberID = MemberTransaction.Member_ID;
                    intTransactionPaymentID = MemberTransaction.TransactionPaymentID;
                }

                db.SubmitChanges();
                //return MemberTransaction.TransactionPaymentID;
            }
            catch (Exception ex)
            {
                ErrHandler.WriteError(ex.Message);
                throw (ex);
            }
        }

        public void UpdateFullPayPal_byTranactionPaymentId(string strToken, string strPayerID, NVPCodec NVPtransaction, int intMemberID, int intTransactionPaymentID)
        {

            try
            {

                MembershipDataContext db = GetMembershipDB();
                var MemberTransaction = (from t1 in db.TransactionPayments
                                         where t1.TransactionPaymentID == intTransactionPaymentID
                                         select t1).Single();

                MemberTransaction.PayerID = strPayerID;
                MemberTransaction.TokenID = strToken;
                MemberTransaction.PaymentAmount = Convert.ToDouble(NVPtransaction["PAYMENTINFO_0_AMT"]);
                MemberTransaction.TransactionID_PayPal = NVPtransaction["PAYMENTINFO_0_TRANSACTIONID"];
                //todo: add nenatransactionID
                //MemberTransaction.TransactionType = NVPtransaction["TRANSACTIONTYPE"];
                //MemberTransaction.PaymentMethod = "PayPal";
                MemberTransaction.PaymentMethod = NVPtransaction["PAYMENTINFO_0_PAYMENTTYPE"];
                MemberTransaction.PaymentStatus = NVPtransaction["PAYMENTINFO_0_PAYMENTSTATUS"];
                MemberTransaction.PayPalFee = Convert.ToDouble(NVPtransaction["PAYMENTINFO_0_FEEAMT"]);
                MemberTransaction.PaymentDate = DateTime.Now;
                MemberTransaction.PaymentReason = "NENA2011Conference";
                if (MemberTransaction.PaymentStatus == "Completed")
                {
                    MemberTransaction.TransactionCompleted = true;
                    intMemberID = MemberTransaction.Member_ID;
                    intTransactionPaymentID = MemberTransaction.TransactionPaymentID;
                }

                db.SubmitChanges();
                //return MemberTransaction.TransactionPaymentID;
            }
            catch (Exception ex)
            {
                ErrHandler.WriteError(ex.Message);
                throw (ex);
            }
        }
    }
}